package com.doraro.platform.module.user.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.doraro.platform.common.exception.ApiGlobalException;
import com.doraro.platform.common.utils.Constant;
import com.doraro.platform.common.utils.ShiroUserUtil;
import com.doraro.platform.module.user.mapper.SysRoleMapper;
import com.doraro.platform.module.user.model.dto.RoleDetail;
import com.doraro.platform.module.user.model.entity.SysMenu;
import com.doraro.platform.module.user.model.entity.SysRole;
import com.doraro.platform.module.user.model.entity.SysRoleMenu;
import com.doraro.platform.module.user.service.ISysMenuService;
import com.doraro.platform.module.user.service.ISysRoleMenuService;
import com.doraro.platform.module.user.service.ISysRoleService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author doraro
 * @since 2019-04-21
 */
@Service
public class SysRoleServiceImpl extends ServiceImpl<SysRoleMapper, SysRole> implements ISysRoleService {
    private final ISysRoleMenuService roleMenuService;
    private final ISysMenuService menuService;
    @Autowired
    public SysRoleServiceImpl(ISysRoleMenuService roleMenuService, ISysMenuService menuService) {
        this.roleMenuService = roleMenuService;
        this.menuService = menuService;
    }

    @Override
    public List<SysRole> getRolesByUserId(String userId) {
        return super.baseMapper.getRoleByUserId(userId);
    }

    @Override
    public Set<String> getPemsByRoleIds(List<Integer> id) {
        final Collection<SysRole> roles = super.listByIds(id);
        if (roles == null || roles.isEmpty()) {
            throw new ApiGlobalException("没有角色");
        }
        //管理员拥有全部权限
        final Optional<SysRole> admin = roles.stream()
                .filter(it -> (Constant.ADMIN_NAME.equals(it.getName())))
                .findFirst();
        if (admin.isPresent()) {
            return menuService.list().stream()
                    .map(SysMenu::getPerm)
                    .filter(StringUtils::isNotEmpty)
                    .collect(Collectors.toSet());
        }
        final List<String> res2 = baseMapper.getMenuResoucePermsByRoleIds(id);
        final HashSet<String> result = new HashSet<>(res2.size());
        result.addAll(res2);
        result.remove("");
        return result;
    }

    @Override
    public List<RoleDetail> listWithMenus() {
        return super.baseMapper.listWithMenuIds();

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void changeRolePermByMenuIds(Integer roleId, List<Integer> menuIds) {
        Objects.requireNonNull(menuIds);
        Objects.requireNonNull(roleId);
        roleMenuService.lambdaUpdate().eq(SysRoleMenu::getRoleId, roleId).remove();
        final List<SysRoleMenu> resources = menuIds.stream().map(it -> {
            final SysRoleMenu sysRoleResource = new SysRoleMenu();
            sysRoleResource.setRoleId(roleId);
            sysRoleResource.setMenuId(it);
            return sysRoleResource;
        }).collect(Collectors.toList());
        roleMenuService.saveBatch(resources, menuIds.size());
        ShiroUserUtil.cleanCache();
    }

    @Override
    public List<SysRole> getPublicRoles() {
        return super.list().stream()
                .filter(role -> !Constant.ADMIN_NAME.equals(role.getName()))
                .collect(Collectors.toList());
    }
}
